package com.hdu.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.hdu.entity.Major;
import com.hdu.entity.School;
import com.hdu.entity.SchoolMajor;
import com.hdu.entity.SchoolScore;
import com.hdu.mapper.MajorMapper;
import com.hdu.mapper.SchoolMapper;
import com.hdu.mapper.SchoolScoreMapper;
import com.hdu.pojo.DataCell;
import com.hdu.pojo.PageBean;
import com.hdu.service.IMajorService;
import com.hdu.vo.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 专业实体类 服务实现类
 * </p>
 *
 * @author xiaobai
 * @since 2023-10-28
 */
@Service
@RequiredArgsConstructor
public class MajorServiceImpl extends ServiceImpl<MajorMapper, Major> implements IMajorService {

    private final MajorMapper majorMapper;

    private final SchoolMapper schoolMapper;

    private final SchoolScoreMapper schoolScoreMapper;

    private final JSONObject batchJson = JSONObject.parseObject("{1564:\"本科一段\",2935:\"第二批\",2674:\"本科第二批\",17:\"平行录取二段\",52:\"本科一批B段\",1561:\"艺术类本科批\",37:\"本科提前批B段\",2777:\"艺术类本科A段\",113:\"本科二批K段\",51:\"本科一批A段\",86:\"本科提前批C段\",1534:\"本科二批及预科\",2726:\"体育类本科批\",8:\"本科二批\",36:\"本科提前批A段\",119:\"高职（专科）批R段\",10:\"专科批\",2929:\"艺术本科二批\",1565:\"本科二段\",16:\"平行录取一段\",2642:\"本科第一批\",2699:\"艺术本科提前批B段\",6:\"本科提前批\",98:\"本科一批A1段\",48:\"专科批A段\",12:\"国家专项计划本科批\",2741:\"艺术类第二批\",2685:\"本科一批U段\",2915:\"艺术类第一批A段\",69:\"本科综合评价批\",1570:\"普通类一段\",15:\"普通类提前批\",2949:\"本科一批T段\",13:\"地方专项计划本科批\",1137:\"高校专项计划本科批\",2583:\"艺术本科A段\",2668:\"艺术本科批B段\",47:\"本科批B段\",2669:\"艺术本科批C段\",46:\"本科批A段\",14:\"本科批\",44:\"本科二批A段\",2667:\"艺术本科批A段\",45:\"本科二批B段\",54:\"本科二批C段\",111:\"本科一批I段\",11:\"专科提前批\",1571:\"普通类二段\",2734:\"体育类第一段\",1939:\"普通类平行录取\",90:\"特殊类型招生批\",7:\"本科一批\"}");

    private final JSONObject typeJson = JSONObject.parseObject("{33:\"蒙授理科\",1157:\"医学类\",24:\"体育理\",2:\"文科\",1085:\"学考理\",1079:\"3+证书\",1144:\"计算机类\",1150:\"旅游类\",26:\"艺术理\",1145:\"农学类\",2295:\"体育类（物理）\",1151:\"汽驾类\",2234:\"学考\",1148:\"财会类\",1156:\"幼师类\",3:\"综合\",1:\"理科\",2074:\"历史类\",23:\"体育文\",5:\"体育类\",2294:\"体育类（历史）\",1084:\"学考文\",1147:\"烹饪类\",32:\"蒙授文科\",1152:\"建筑类\",25:\"艺术文\",31:\"蒙授体育\",4:\"艺术类\",2073:\"物理类\",2293:\"艺术类（物理）\",2292:\"艺术类（历史）\"}");


    @Override
    public PageBean<MajorList> majorPage(Integer current, Integer size, String level, String kind, String type, String order, String name) {

        Page<Major> page = new Page<>(current, size);

        QueryWrapper<Major> wrapper = new QueryWrapper<>();
        wrapper.eq(StrUtil.isNotEmpty(level), "level", level)
                .eq(StrUtil.isNotEmpty(kind), "kind", kind)
                .eq(StrUtil.isNotEmpty(type), "type", type)
                .orderByDesc(StrUtil.isNotEmpty(order), order)
                .like(StrUtil.isNotEmpty(name), "name", name)
                .isNotNull("code");

        IPage<Major> iPage = majorMapper.selectPage(page, wrapper);

        return new PageBean<>(iPage.getTotal(), BeanUtil.copyToList(iPage.getRecords(), MajorList.class));
    }

    @Override
    public List<MajorSelect> navigation() {
        QueryWrapper<Major> wrapper = new QueryWrapper<>();
        wrapper.select("level").last("group by level");
        List<Object> list = majorMapper.selectObjs(wrapper);
        return MajorSelect(list, 1);
    }

    private List<MajorSelect> MajorSelect(List<Object> list, Integer level) {
        String[] att = {"level", "kind", "type"};
        List<MajorSelect> majorSelects = new ArrayList<>();
        list.remove("其他");
        for (Object object : list) {
            MajorSelect majorSelect = new MajorSelect((String) object, new ArrayList<>());
            QueryWrapper<Major> wrapper = new QueryWrapper<>();
            if (level != 3) {
                wrapper.eq(att[level - 1], object).isNotNull("code").isNotNull(att[level]).select(att[level]).last("group by " + att[level]);
                majorSelect.setChildren(MajorSelect(majorMapper.selectObjs(wrapper), level + 1));
            }
            majorSelects.add(majorSelect);
        }
        return majorSelects;
    }

    @Override
    public RankSelect rankSelect(String name, Integer region, String year) {
        QueryWrapper<SchoolScore> wrapperType = new QueryWrapper<>();
        QueryWrapper<SchoolScore> wrapperBatch = new QueryWrapper<>();
        List<DataCell> typeList = new ArrayList<>();
        List<DataCell> batchList = new ArrayList<>();
        wrapperType.select("type").like("name", name).eq("year", year).eq("region", region).last("group by type");
        wrapperBatch.select("batch").like("name", name).eq("year", year).eq("region", region).last("group by batch");
        for (Object batch : schoolScoreMapper.selectObjs(wrapperBatch)) {
            batchList.add(DataCell.of(batchJson.getString(String.valueOf(batch)), batch));
        }
        for (Object type : schoolScoreMapper.selectObjs(wrapperType)) {
            typeList.add(DataCell.of(typeJson.getString(String.valueOf(type)), type));
        }
        return new RankSelect(typeList, batchList);
    }

    @Override
    public PageBean<RankTable> rank(Integer current, Integer size, String name, Integer region, Integer batch, Integer type, String year, String level, String special, String mold, String province) {

        IPage<RankTable> iPage = schoolMapper.selectJoinPage(new Page<>(current, size), RankTable.class,
                new MPJLambdaWrapper<School>()
                        .selectAll(SchoolScore.class)
                        .select(School::getCover)
                        .selectAs(School::getName, "title")
                        .leftJoin(SchoolScore.class, SchoolScore::getSchoolId, School::getId)
                        .eq(special.equals("f211"), School::getF211, 1)
                        .eq(special.equals("f985"), School::getF985, 1)
                        .eq(special.equals("duality"), School::getDuality, 1)
                        .eq(special.equals("admission"), School::getAdmission, 1)
                        .eq(StrUtil.isNotEmpty(mold), School::getType, mold)
                        .eq(StrUtil.isNotEmpty(province), School::getProvince, province)
                        .eq(StrUtil.isNotEmpty(level), School::getType, level)
                        .eq(region != null, SchoolScore::getRegion, region)
                        .eq(type != null, SchoolScore::getType, type)
                        .eq(batch != null, SchoolScore::getBatch, batch)
                        .eq(StrUtil.isNotEmpty(year), SchoolScore::getYear, year)
                        .like(name != null, SchoolScore::getName, name)
                        .orderByDesc("min_score"));
        return new PageBean<>(iPage.getTotal(), iPage.getRecords());
    }

    @Override
    public PageBean<SchoolList> schoolPage(Integer current, Integer size, Integer id, String level, String region, String type, String special) {
        IPage<SchoolList> iPage = schoolMapper.selectJoinPage(new Page<>(current, size), SchoolList.class,
                new MPJLambdaWrapper<School>()
                        .selectAll(School.class)
                        .select(SchoolMajor::getRuan)
                        .rightJoin(SchoolMajor.class, SchoolMajor::getSchoolId, School::getId)
                        .eq(special.equals("f211"), School::getF211, 1)
                        .eq(special.equals("f985"), School::getF985, 1)
                        .eq(special.equals("duality"), School::getDuality, 1)
                        .eq(special.equals("admission"), School::getAdmission, 1)
                        .eq(StrUtil.isNotEmpty(type), School::getType, type)
                        .eq(StrUtil.isNotEmpty(region), School::getProvince, region)
                        .eq(StrUtil.isNotEmpty(level), School::getType, level)
                        .isNotNull(SchoolMajor::getRuan)
                        .orderByAsc(SchoolMajor::getRuan)
                        .eq(SchoolMajor::getMajorId, id));
        return new PageBean<>(iPage.getTotal(), iPage.getRecords());
    }
}
